#include <libdswserver/dswavserver.h>
#include <libdswsession/dswavsession.h>
#include <libdswsession/dswavfwdsession.h>

CDswavserver::CDswavserver(LPST_ENV_T pEnv, int nPort)
: CDswtcpserver_base(pEnv, nPort)
, m_pClientTable(NULL)
{
	LOG4CPLUS_DEBUG(log_dsw, "Create CDswavserver class! server port [ " << nPort << " ]");
	m_pClientTable = HashTable::create(STRING_HASH_KEYS);
	pthread_mutex_init(&m_nLock, NULL);
}

CDswavserver::~CDswavserver()
{
	LOG4CPLUS_DEBUG(log_dsw, "Destroy CDswavserver class!");
	MUTEX_LOCK(&m_nLock);
	if (m_pClientTable != NULL){
		while (m_pClientTable->RemoveNext() != NULL);
	}
	MUTEX_UNLOCK(&m_nLock);
	pthread_mutex_destroy(&m_nLock);
	delete m_pClientTable;
}

void CDswavserver::OnAccept(evutil_socket_t fd, struct sockaddr *address, int socklen)
{
	char sKey[64];
	struct sockaddr_in *client = (struct sockaddr_in*)address;
	sprintf(sKey, "%s:%d", inet_ntoa(client->sin_addr), ntohs(client->sin_port));
	new  CDswavsession(m_pEnv, evconnlistener_get_base(m_pListener), fd, sKey);
}

int CDswavserver::OnMessage(EN_MSG_TYPE nMsgType, void * pParam)
{
	MUTEX_LOCK(&m_nLock);
	switch(nMsgType){
	case PMSG_GET_TOTALREC_UPDATE:
	case PMSG_SET_UPDATE_TIMEZ:
		{
			CDswavsession* pSession;
			HashTable::Iterator* iter = HashTable::Iterator::create(*m_pClientTable);
			char const* key;
			while((pSession = (CDswavsession*)iter->next(key)) != NULL){
				pSession->HandleMessage(nMsgType, pParam);
			}
			delete iter;
		}
		break;
	case PMSG_GET_ISLIVEVIDEO:
		*(bool*)pParam = !m_pClientTable->IsEmpty();
		break;
	case PMSG_SET_UPDATE_FWDSESSION:
		{
			char sKey[512];
			LPST_TRANS_REQ_T pTransReq = (LPST_TRANS_REQ_T)pParam;
			sprintf(sKey, "%s_%d_%d", FWD_KEY, pTransReq->nCh, pTransReq->bLocal);
			CDswavfwdsession* pSession = (CDswavfwdsession*)m_pClientTable->Lookup(sKey);
			if (pSession != NULL){
				pSession->AddNewTransOrder(pTransReq->sPUCId);
				pTransReq->bAdded = true;
			}
			else
				pTransReq->bAdded = false;
		}
		break;
	case PMSG_SET_AVSESSION_ADD:
		{
			LPST_SESSION_NOTIFY_T pNotify = (LPST_SESSION_NOTIFY_T)pParam;
			if (m_pClientTable->Lookup(pNotify->pKey)){
				pNotify->bRet = false;
			}
			else{
				m_pClientTable->Add(pNotify->pKey, pNotify->pClass);
				pNotify->bRet = true;
				LOG4CPLUS_DEBUG(log_dsw, "Add session [ " << pNotify->pKey << " ] !");
			}
		}
		break;
	case PMSG_SET_AVSESSION_REMOVE:
		{
			LPST_SESSION_NOTIFY_T pNotify = (LPST_SESSION_NOTIFY_T)pParam;
			m_pClientTable->Remove(pNotify->pKey);
			LOG4CPLUS_DEBUG(log_dsw, "Remove session [ " << pNotify->pKey << " ] !");
		}
		break;
	case PMSG_SET_REC_VIDEO_OP:
		{
			LPST_PLAYBACK_OP_T pOp = (LPST_PLAYBACK_OP_T)pParam;
			CDswavsession* pSession;
			HashTable::Iterator* iter = HashTable::Iterator::create(*m_pClientTable);
			char const* key;
			while((pSession = (CDswavsession*)iter->next(key)) != NULL){
				printf("jjjjjj pucid = %s, key = %s, op pucid = %s\n", pSession->GetPucId(), pSession->GetKey(), pOp->sPucId);
#if 0
				if ((strcmp(pSession->GetPucId(), pOp->sPucId) == 0) ||
					(strstr(FWD_KEY, key) != NULL)){
					pSession->HandleMessage(nMsgType, pParam);
					break;
				}
#else
				if (strcmp(pSession->GetPucId(), pOp->sPucId) == 0){
					pSession->HandleMessage(nMsgType, pParam);
					break;
				}
				else if (strstr(key, FWD_KEY)){
					if (strcmp(key, pSession->GetKey()) == 0){
						pSession->HandleMessage(nMsgType, pParam);
						break;
					}
				}
#endif
			}
			delete iter;
		}
		break;
	}
	MUTEX_UNLOCK(&m_nLock);
	return 0;
}

